//go:build windows
// +build windows

package 浏览器类

import (
	"errors"
	"fmt"
	下载类 "gitee.com/go_888/extends/downloader"
	扩展类 "gitee.com/go_888/extends/extend"
	文件类 "gitee.com/go_888/extends/goframe/gfile"
	浏览器环境类 "gitee.com/go_888/webview2/internal/EdgeRuntime"
	浏览器函数类 "gitee.com/go_888/webview2/internal/webviewloader"
	"path/filepath"
	"strconv"
	"strings"
)

// 提示用于配置窗口大小和调整大小行为。
type X尺寸类型 int

const (
	X常量_尺寸类型_默认 X尺寸类型 = iota //指定宽度和高度为默认尺寸
	X常量_尺寸类型_固定              //指定用户无法更改窗口大小
	X常量_尺寸类型_最小              //指定宽度和高度为最小边界
	X常量_尺寸类型_最大              //指定宽度和高度为最大边界
)

// 在错误定义之后添加
// X热键处理程序 是热键处理函数的类型
type X热键处理程序 func()

// X设置webview2路径 设置webview2组件的路径
// 参数:
// 路径: 指定webview2组件的文件路径，用于初始化webview2控件
func X设置webview2路径(路径 string) {
	webview2路径 = 路径
}

//TODO 改成动画形式 https://pkg.go.dev/image/gif 使用这个包可以提取动画数据.

// X检查webview2并下载 根据指定的目录和下载地址设置WebView2的路径，并在需要时下载WebView2。
// 参数 edge目录: WebView2将要被解压的目录路径。
// 参数 zip下载地址: WebView2的zip文件下载地址。
// 参数 最低主版本: 系统中已安装的WebView2的最低主版本号,默认为109(win7能接受的最高版本)
// 返回值 error: 如果操作失败，则返回错误信息。
func X检查webview2并下载(edge目录, zip下载地址 string, 最低主版本 int) error {
	// 检查edge目录和zip下载地址是否为空，如果为空，则返回错误。
	if edge目录 == "" || zip下载地址 == "" {
		return errors.New("edge目录或zip下载地址不能为空")
	}
	// 如果最低主版本小于等于0，则将其设置为默认值109。
	if 最低主版本 <= 0 {
		最低主版本 = 109
	}

	// 获取已安装的WebView2的主版本号。
	主版本, err := X取已安装WebView2主版本()
	if err != nil {
		fmt.Println(err)
		return err
	}
	// 构建msedgewebview2.exe的路径。
	exePath := filepath.Join(edge目录, "msedgewebview2.exe")
	// 如果msedgewebview2.exe存在，则设置webview2路径为edge目录，并返回nil表示成功。
	if 文件类.X是否存在文件(exePath) {
		webview2路径 = edge目录
		return nil
	}
	// 如果已安装的WebView2的主版本号大于等于最低主版本，则无需下载，直接返回nil。
	if 主版本 >= 最低主版本 {
		return nil
	}

	// 如果已安装的WebView2的主版本号小于最低主版本，则需要下载。
	go 浏览器环境类.X运行窗口()
	// 下载zip文件到字节集。
	字节集, err := 下载类.X下载文件到字节集(zip下载地址, 20, func(进度 下载类.X进度详情) bool {
		// 如果浏览器环境未关闭，则更新下载进度。
		if 浏览器环境类.X是否已关闭() == false {
			浏览器环境类.X追加日志("下载进度:" + 进度.X进度文本 + "  每秒速度:" + 进度.X每秒速度)
		} else {
			扩展类.X结束() // 用户主动关闭窗口
		}
		return true
	})

	// 如果下载过程中出现错误，则记录错误信息并等待用户关闭浏览器环境。
	if err != nil {
		浏览器环境类.X追加日志("错误:" + err.Error())
		浏览器环境类.X追加日志("下载环境失败, 请稍后重试....")
		for {
			if 浏览器环境类.X是否已关闭() { // 等待用户关闭
				扩展类.X结束()
			}
			扩展类.X延时(100)
		}
	}

	// 开始解压zip文件。
	浏览器环境类.X追加日志("正在解压,预计一分钟...")
	// 解压字节集到指定目录。
	err = 扩展类.Zip字节集解压(字节集, edge目录)
	if err != nil {
		浏览器环境类.X追加日志("\n解压出错:" + err.Error())
		// 如果解压过程中出现错误，则等待用户关闭浏览器环境。
		for {
			if 浏览器环境类.X是否已关闭() { // 等待用户关闭
				扩展类.X结束()
			}
			扩展类.X延时(100)
		}
	}

	// 关闭浏览器环境，并设置webview2路径为edge目录。
	浏览器环境类.X关闭()
	webview2路径 = edge目录
	return nil
}

// X取已安装WebView2主版本 获取已安装的 WebView2 浏览器主版本号。
// 返回:
//   - int: 主版本号
//   - error: 错误信息
func X取已安装WebView2主版本() (int, error) {
	// 获取完整的 WebView2 版本号字符串
	version, err := X取已安装WebView2版本()
	if err != nil {
		return 0, fmt.Errorf("获取 WebView2 版本失败: %v", err)
	}

	if version == "" {
		return 0, fmt.Errorf("未找到已安装的 WebView2 版本")
	}

	// 分割版本号字符串
	parts := strings.Split(version, ".")
	if len(parts) == 0 {
		return 0, fmt.Errorf("版本号格式不正确")
	}

	// 转换主版本号为整数
	mainVersion, err := strconv.Atoi(parts[0])
	if err != nil {
		return 0, fmt.Errorf("无法将主版本号转换为整数: %v", err)
	}

	return mainVersion, nil
}

// X取已安装WebView2版本 获取当前系统中安装的WebView2浏览器的版本信息。
// 该函数不接受任何参数。
// 返回值为字符串类型，表示WebView2的版本号；错误类型用于返回可能发生的错误。
// 主要用途是调用浏览器函数类中的相应方法来获取WebView2版本信息。
func X取已安装WebView2版本() (string, error) {
	return 浏览器函数类.X取已安装WebView2版本()
}

// JS钩子类型 定义 Hook 的类型
type JS钩子类型 int

const (
	X常量_JS钩子类型_JS执行前 JS钩子类型 = iota // JS 执行前
	X常量_JS钩子类型_JS执行后               // JS 执行后
)

// X接口_JS钩子 定义 JavaScript 钩子接口
type X接口_JS钩子 interface {
	X钩子类型() JS钩子类型              // 获取 Hook 类型
	X处理函数(script string) string // 处理脚本
	X优先级() int                  // Hook 优先级，数字越小优先级越高
}

// X结构_JS钩子 提供基本的 JSHook 实现
type X结构_JS钩子 struct {
	HookType     JS钩子类型
	Handler      func(script string) string
	HookPriority int
}

func (h *X结构_JS钩子) X钩子类型() JS钩子类型 {
	return h.HookType
}

func (h *X结构_JS钩子) X处理函数(script string) string {
	if h.Handler != nil {
		return h.Handler(script)
	}
	return script
}

func (h *X结构_JS钩子) X优先级() int {
	return h.HookPriority
}
